﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


using System.IO;
using HA.ModFlow.Infrastructure;

namespace HA.ModFlow.Domain.DomainLayer
{
   public  class IBoundTxtFileReader
    {

       public IBoundTxtFileReader()
       { 
       
       
       }


       #region 字段属性

       ///// <summary>
       ///// 文件路径
       ///// </summary>
       //private  static  string _path;
       ///// <summary>
       ///// RowNumber
       ///// </summary>
       //private static int _i;
       ///// <summary>
       ///// ColNumber
       ///// </summary>
       //private static int _j;
       ///// <summary>
       ///// LayerNumber
       ///// </summary>
       //private static int _k;
       ///// <summary>
       ///// 应力期个数
       ///// </summary>
       //private static int _nPeriods;
       ///// <summary>
       ///// 各应力期的时间步数
       ///// </summary>
       //private static List<int> _stressPeriodNSTP;

       //private static OutputControl _oc;






       #endregion

       /// <summary>
       /// 读取 边界txt文件 IBound 的结果
       /// </summary>
       /// <param name="path">文件路径（不包括文件名和后缀）</param>
       /// <param name="i">主网格 RowsNumber</param>
       /// <param name="j">主网格 ColsNumber</param>
       /// <param name="k"> 主网格 LayerNumber</param>
       /// <param name="nPeriods">应力期总个数</param>
       /// <param name="stressPeriodNSTP">各应力期的时间步数</param>
       /// <param name="oc">应力期输出类型</param>
       public static List<int[,,]> ReadIBoundTxtFile(string path, int i, int j, int k, int nPeriods, List<int> stressPeriodNSTP, OutputControl oc)
       {

           List<int[, ,]> resultIBound = new List<int[, ,]>();

           if (oc == null || stressPeriodNSTP==null )
           {
               return resultIBound;
           }




           try
           {


               //说明：该读取文件数据的方法的做了一些前提的假设  1，文件内容很规范，从第一行开始就是数据信息，且数据完整
               //2，数据之间没有空行

               //其他的情况可能会导致该方法读取文件错误


               //以 15*15*3 的网格 ；总共 4 个应力期 ；每个应力期 时间步数都为 10   ；输出所有时间步数应力期；输出格式 _10G11_4。

               #region 取得控制参数 以明确输出的文件结构

               int mLen = 12;//每个完整的数据占12位  包括负号的情况
               int maxLength = 10;//默认每行最多有10个完整数据


               //总共需要的网格数

               int gridNumber = 0;

               //如果是应力期每个步长输出
               //gridNumber=第一个应力期时间步数 + 第二个应力期时间步数 + 第三个应力期时间步数 + 第四个应力期时间步数 
               //如果是应力期输出最后一个步长
               //gridNumber=应力期总的个数

               if (oc.IsAllStepOutput == true)
               {
                   for (int nstp = 0; nstp < stressPeriodNSTP.Count; nstp++)
                   {
                       gridNumber = gridNumber + stressPeriodNSTP[nstp];
                   }
                   //共有 40 个网格
               }
               else
               {
                   gridNumber = nPeriods;
                   //共有4个网格

               }




               //网格每个I（Row）在文件中占多少行
               //默认设置 _10G11_4   每行最多10个完整数据，每个数据占11位，显示4位小数，例如：-0.2166E-02
               if (j <= 10)
               {
                   //1行  
               }
               if (10 < j && j <= 20)
               {
                   //2行 
               }
               //类推  有待验证
               double result = j * 0.1;//默认每行最多 10 个完整数据 所以乘以 0.1
               int lineNum = (int)Math.Ceiling(result);
               //占 2 行


               //网格每层在文件中站多少行
               int layerLineNumber = 0;
               //layerLineNumber= I（RowsNumber）* 网格每个I（Row）在文件中占行

               layerLineNumber = lineNum * i;
               //30 行


               //每个网格在文件站多少行

               int gridLineNumber = 0;
               //gridLineNumber=layerLineNumber*K;
               gridLineNumber = layerLineNumber * k;
               //90 行



               //文件总的数据行数

               int fileLineNumber = 0;
               //fileLineNumber=gridLineNumber * gridNumber(应力期总个数)
               fileLineNumber = gridLineNumber * gridNumber;
               //3600 行

               #endregion



               string FileName = path + "IBOUUN.dat";

               if (System.IO.File.Exists(FileName))
               {
                   StreamReader sr = new StreamReader(FileName);

                   try
                   {
                       resultIBound.Clear();
                       // 记录 应力期_时间步长_传输步长
                       bool isAllStepOutputType = oc.IsAllStepOutput;//应力期的输出类型
                       int stressIndex = 1;//第几个应力期  应力期总个数 this._stressPeriodNSTP.Count
                       int timeIndex = 1;//第几个时间步长   某个应力期的总时间步长 _stressPeriodNSTP[i]=10




                       for (int gnum = 0; gnum < gridNumber; gnum++)//总共多少个网格的数据
                       {

                           #region 更新应力期 时间步长的标记

                           if (isAllStepOutputType == true)
                           {

                               if (gnum == 0)
                               {
                                   stressIndex = 1;
                                   timeIndex = 1;
                               }
                               else
                               {
                                   timeIndex = timeIndex + 1;

                                   if (timeIndex <= stressPeriodNSTP[stressIndex - 1])
                                   {
                                       //timeIndex = timeIndex + 1;

                                   }
                                   else if (timeIndex > stressPeriodNSTP[stressIndex - 1])
                                   {
                                       timeIndex = 1;
                                       stressIndex = stressIndex + 1;
                                   }

                               }


                           }
                           else
                           {

                               if (gnum == 0)
                               {
                                   stressIndex = 1;
                                   timeIndex = stressPeriodNSTP[stressIndex - 1];
                               }
                               else
                               {
                                   stressIndex = stressIndex + 1;

                                   timeIndex = stressPeriodNSTP[stressIndex - 1];

                               }


                           }

                           #endregion



                           int[, ,] gridValue = new int[i, j, k];


                           //Grid3dValue Grid3d = new Grid3dValue(_i, _j, _k);


                           //从文件中读取对应网格的信息

                           int row = 0;
                           int col = 0;
                           int layer = 0;


                           #region 从文件读取网格信息  按照逐个网格的方式处理

                           int reanLineNumber = 0;//记录读取某一个网格的时候，从文件中读取的总行数，用以判断读取一个网格的数据是否结束

                           int readEndColNum = 0;//每个I（Row）占多行时，记录读取的局部行数，用以判断读取I（Row）是否结束

                           //下面使用 do   while  循环  读取数据，while中负责判断是否读到文件末尾或是否读完了一个网格的数据


                           string str = null;
                           do
                           {
                               //循环读取一个网格的数据信息

                               #region

                               str = sr.ReadLine();

                               reanLineNumber = reanLineNumber + 1;


                               if (str == null)
                               {
                                   resultIBound.Clear();

                                   break;//当文件中间有空行不是连续的数据的时候  表示文件被破坏
                                   //continue;
                               }
                               if (str.Trim() == "")
                               {
                                   resultIBound.Clear();

                                   break;//当文件中间有空行不是连续的数据的时候  表示文件被破坏
                                   //continue;
                               }
                               if (lineNum <= 1)//网格每个I（Row）在文件中占1行
                               {
                                   #region

                                   for (int index = 0; index < j; index++)
                                   {
                                       //遍历读取完整数据 

                                       string colStr = str.Substring(index * mLen, mLen);

                                       int rowColData = Convert.ToInt32(colStr);

                                       //Grid3d.Datas[row, index, layer] = rowColData;

                                       gridValue[row, index, layer] = rowColData;

                                   }
                                   if (row + 1 >= i)//判断是否读完了一层
                                   {
                                       row = 0;
                                       layer = layer + 1;//改变层的标记
                                   }
                                   else
                                   {
                                       row = row + 1;//记录正在读取网格的哪一个Row
                                   }

                                   #endregion

                               }
                               else
                               {
                                   readEndColNum = readEndColNum + 1;//个数
                                   if (readEndColNum > lineNum)//I（Row）对应的数据读完，进入下一个Row
                                   {
                                       row = row + 1;
                                       col = 0;
                                       readEndColNum = 1;
                                   }
                                   if (row + 1 > i)//判断是否读完了一层
                                   {
                                       row = 0;
                                       col = 0;
                                       layer = layer + 1;//改变层的标记
                                   }
                                   //else
                                   //{
                                   //    row = row + 1;//记录正在读取网格的哪一个Row
                                   //    col = 0;
                                   //}


                                   if (readEndColNum == lineNum)
                                   {
                                       for (int index = 0; index < j - (lineNum - 1) * maxLength; index++)
                                       {
                                           //遍历读取完整数据 

                                           string colStr = str.Substring(index * mLen, mLen);

                                           int rowColData = Convert.ToInt32(colStr);

                                           //Grid3d.Datas[row, col, layer] = rowColData;

                                           gridValue[row, col, layer] = rowColData;

                                           col = col + 1;

                                       }

                                   }
                                   else
                                   {
                                       for (int index = 0; index < maxLength; index++)
                                       {
                                           //遍历读取完整数据 

                                           string colStr = str.Substring(index * mLen, mLen);

                                           int rowColData = Convert.ToInt32(colStr);

                                           //Grid3d.Datas[row, col, layer] = rowColData;

                                           gridValue[row, col, layer] = rowColData;

                                           col = col + 1;
                                       }

                                   }

                                   #region


                                   #endregion

                               }

                               #endregion
                           }
                           while (sr.EndOfStream != true && reanLineNumber < gridLineNumber);


                           #endregion 从文件读取网格信息 结束




                           if (str == null)
                           {
                               break;
                           }
                           else if (str.Trim() == "")
                           {
                               break;
                           }
                           else
                           {
                               if (gridValue == null)
                               {
                                   //默认全部为1
                                   gridValue = new int[i, j, k];
                                   for (int rowIndex = 0; rowIndex < i; rowIndex++)
                                   {
                                       for (int colIndex = 0; colIndex < j; colIndex++)
                                       {
                                           for (int layerIndex = 0; layerIndex < k; layerIndex++)
                                           {
                                               gridValue[rowIndex, colIndex, layerIndex] = 1;
                                           }
                                       }
                                   }

                               }

                               resultIBound.Add(gridValue);

                           }


                       }//  for (int gnum = 0; gnum < gridNumber; gnum++)//总共多少个网格的数据  结束



                       sr.Close();



                   }
                   catch
                   {
                       System.Windows.Forms.MessageBox.Show("读取结果文件 IBOUUN.dat 出错了！");

                       resultIBound.Clear();

                       sr.Close();


                   }

               
               }


               return resultIBound;
           }
           catch 
           {
               resultIBound = new List<int[, ,]>();

               return resultIBound;
           }

       }








    }
}
